#ifndef PERMISSIONMANAGER_H
#define PERMISSIONMANAGER_H

#include <QObject>
#include <QString>
#include <QStringList>
#include <QMap>
#include <QSet>
#include "usersession.h"

// Permission enumeration
typedef enum {
    PERM_DEVICE_CONTROL = 0,    // Device control permissions
    PERM_SAMPLING_MANAGE,       // Sampling management
    PERM_USER_MANAGE,           // User management
    PERM_DATA_VIEW,             // Data viewing
    PERM_DATA_EXPORT,           // Data export
    PERM_SYSTEM_CONFIG,         // System configuration
    PERM_AUDIT_VIEW,            // Audit log viewing
    PERM_BACKUP_RESTORE,        // Backup and restore
    PERM_MAINTENANCE            // System maintenance
} Permission;

// Permission group structure
typedef struct {
    QString groupName;          // Permission group name
    QString description;        // Group description
    QSet<Permission> permissions; // Permissions in this group
} PermissionGroup;

class PermissionManager : public QObject
{
    Q_OBJECT

public:
    explicit PermissionManager(QObject *parent = nullptr);
    ~PermissionManager();

    // Initialize with user session
    bool initialize(UserSession* userSession);

    // Permission checking methods
    bool hasPermission(const QString& username, Permission permission) const;
    bool hasPermission(const QString& username, const QString& permissionStr) const;
    bool hasAnyPermission(const QString& username, const QList<Permission>& permissions) const;
    bool hasAllPermissions(const QString& username, const QList<Permission>& permissions) const;

    // Role-based permission methods
    QSet<Permission> getRolePermissions(UserRole role) const;
    bool setRolePermissions(UserRole role, const QSet<Permission>& permissions);
    
    // User-specific permission methods (overrides)
    QSet<Permission> getUserPermissions(const QString& username) const;
    bool setUserPermissions(const QString& username, const QSet<Permission>& permissions);
    bool addUserPermission(const QString& username, Permission permission);
    bool removeUserPermission(const QString& username, Permission permission);
    bool clearUserPermissions(const QString& username);

    // Permission group methods
    QList<PermissionGroup> getPermissionGroups() const;
    bool createPermissionGroup(const QString& groupName, const QString& description, 
                              const QSet<Permission>& permissions);
    bool deletePermissionGroup(const QString& groupName);
    bool assignGroupToUser(const QString& username, const QString& groupName);
    bool removeGroupFromUser(const QString& username, const QString& groupName);

    // Utility methods
    QString permissionToString(Permission permission) const;
    Permission stringToPermission(const QString& permissionStr) const;
    QStringList getAllPermissionStrings() const;
    QString getPermissionDescription(Permission permission) const;

    // Current user convenience methods
    bool currentUserHasPermission(Permission permission) const;
    bool currentUserHasPermission(const QString& permissionStr) const;
    QSet<Permission> getCurrentUserPermissions() const;

    // Configuration methods
    bool loadPermissionConfig();
    bool savePermissionConfig();
    void resetToDefaultPermissions();

signals:
    void permissionsChanged(const QString& username);
    void rolePermissionsChanged(UserRole role);
    void permissionGroupCreated(const QString& groupName);
    void permissionGroupDeleted(const QString& groupName);

private slots:
    void onUserChanged(const QString& username);
    void onUserDeleted(const QString& username);

private:
    // Private methods
    void setupDefaultPermissions();
    void setupDefaultGroups();
    QSet<Permission> combinePermissions(const QString& username) const;
    bool isValidPermission(Permission permission) const;

    // Member variables
    UserSession* m_userSession;
    QMap<UserRole, QSet<Permission>> m_rolePermissions;
    QMap<QString, QSet<Permission>> m_userPermissions;
    QMap<QString, QSet<QString>> m_userGroups;
    QList<PermissionGroup> m_permissionGroups;
    QString m_configFilePath;
};

#endif // PERMISSIONMANAGER_H